home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / mint / filesys / ofake.zoo / src / fakefs.c < prev    next >
C/C++ Source or Header  |  1991-11-17  |  8KB  |  393 lines

  1. #include "atarierr.h"
  2. #include "filesys.h"
  3. #include <string.h>
  4.  
  5. #define DOM_TOS 0
  6. #define DOM_MINT 1
  7. #define NUM_DRIVES 32
  8.  
  9. #ifndef NULL
  10. #define NULL 0L
  11. #endif
  12.  
  13. /*
  14.  * this points to the structure that has all the useful functions that
  15.  * the kernel told us about
  16.  */
  17.  
  18. struct kerinfo *kernel;
  19.  
  20. #define CCONWS (void)(*kernel->dos_tab[0x09])
  21. #define FGETDTA (*kernel->dos_tab[0x2f])
  22. #define RWABS (*kernel->bios_tab[4])
  23. #define GETBPB (void *)(*kernel->bios_tab[7])
  24. #define DEBUG (*kernel->debug)
  25. #define ALERT (*kernel->alert)
  26. #define TRACE (*kernel->trace)
  27. #define FATAL (*kernel->fatal)
  28. #define P_(x) ()
  29.  
  30. int fakedrv = 0;
  31.  
  32. long    fake_root    P_((int drv, fcookie *fc));
  33. long    fake_lookup    P_((fcookie *dir, char *name, fcookie *fc));
  34. long    fake_getxattr    P_((fcookie *fc, XATTR *xattr));
  35. long    fake_chattr    P_((fcookie *fc, int attrib));
  36. long    fake_chown    P_((fcookie *fc, int uid, int gid));
  37. long    fake_chmode    P_((fcookie *fc, unsigned mode));
  38. long    fake_rmdir    P_((fcookie *dir, char *name));
  39. long    fake_remove    P_((fcookie *dir, char *name));
  40. long    fake_getname    P_((fcookie *root, fcookie *dir, char *pathname));
  41. long    fake_rename    P_((fcookie *olddir, char *oldname,
  42.                     fcookie *newdir, char *newname));
  43. long    fake_opendir    P_((DIR *dirh, int flags));
  44. long    fake_readdir    P_((DIR *dirh, char *nm, int nmlen, fcookie *));
  45. long    fake_rewinddir    P_((DIR *dirh));
  46. long    fake_closedir    P_((DIR *dirh));
  47. long    fake_pathconf    P_((fcookie *dir, int which));
  48. long    fake_dfree    P_((fcookie *dir, long *buf));
  49. DEVDRV *    fake_getdev    P_((fcookie *fc, long *devsp));
  50. long    fake_symlink    P_((fcookie *dir, char *name, char *to));
  51. long    fake_readlink    P_((fcookie *fc, char *buf, int buflen));
  52. long    fake_dskchng    P_((int drv));
  53. long errinvfn();
  54.  
  55. FILESYS fake_filesys = {
  56.     (FILESYS *)0,
  57.     0,
  58.     fake_root,
  59.     fake_lookup, errinvfn, fake_getdev, fake_getxattr,
  60.     fake_chattr, fake_chown, fake_chmode,
  61.     errinvfn, fake_rmdir, fake_remove, fake_getname, fake_rename,
  62.     fake_opendir, fake_readdir, fake_rewinddir, fake_closedir,
  63.     fake_pathconf, fake_dfree, errinvfn, errinvfn,
  64.     fake_symlink, fake_readlink, errinvfn, errinvfn, fake_dskchng
  65. };
  66.  
  67. typedef long (*Longfunc)();
  68. Longfunc oldgetbpb, oldmediach, oldrwabs;
  69. extern long newrwabs(), newmediach(), newgetbpb();    /* see below */
  70.  
  71. /* struct used by Fsfirst/Fsnext */
  72. typedef struct _dta {
  73.     char        dta_buf[21];
  74.     char        dta_attribute;
  75.     unsigned short    dta_time;
  76.     unsigned short    dta_date;
  77.     long        dta_size;
  78.     char        dta_name[14];
  79. } _DTA;
  80.  
  81. /*
  82.  * this must be the first function; it is called by the kernel when the
  83.  * file system is being loaded, and should return the file system
  84.  * structure
  85.  */
  86.  
  87. FILESYS *
  88. fake_init(k)
  89.     struct kerinfo *k;
  90. {
  91.     _DTA *d;
  92.     static char foo[] = "x:";
  93.     char drvlet;
  94.  
  95.     kernel = k;
  96.  
  97. /* we decide which device is going to be fake based upon the
  98.  * name we were loaded with (available in the current DTA
  99.  * buffer)
  100.  */
  101.     d = (_DTA *)FGETDTA();
  102.     drvlet = d->dta_name[0];
  103.     if (drvlet >= 'a' && drvlet <= 'z') {
  104.         fakedrv = drvlet - 'a';
  105.     } else {
  106.         fakedrv = drvlet - 'A';
  107.     }
  108.  
  109.     foo[0] = fakedrv + 'A';
  110.  
  111.     if (fakedrv < 0 || fakedrv > 15) {
  112.         CCONWS("Cannot install fake drive ");
  113.         CCONWS(foo);
  114.         CCONWS(" -- try renaming your .XFS file\r\n");
  115.         return 0;
  116.     }
  117.  
  118.     if ( (*((long *)0x4c2)) & (1L << fakedrv) ) {
  119.         CCONWS("Drive "); CCONWS(foo);
  120.         CCONWS(" already exists -- it can't be made fake\r\n");
  121.         return 0;
  122.     }
  123.  
  124. /* install a fake BIOS device */
  125. /* we also have to put in some fake drivers for Getbpb, etc */
  126.     oldrwabs = *((Longfunc *)0x476);
  127.     oldgetbpb = *((Longfunc *)0x472);
  128.     oldmediach = *((Longfunc *)0x47e);
  129.  
  130.     *((Longfunc *)0x476) = newrwabs;
  131.     *((Longfunc *)0x472) = newgetbpb;
  132.     *((Longfunc *)0x47e) = newmediach;
  133.     
  134.     *((long *)0x4c2) |= (1L << fakedrv);
  135.  
  136.     CCONWS("Loaded fake universal device for drive ");
  137.     CCONWS(foo);
  138.     CCONWS("\r\n");
  139.  
  140.     return &fake_filesys;
  141. }
  142.  
  143. long
  144. errinvfn()
  145. {
  146.     DEBUG("Invalid function called on fake file system.");
  147.     return EINVFN;
  148. }
  149.  
  150. /*
  151.  * this is rather ugly; what it does is step through the file system
  152.  * chain looking for the universal drive (drive U:), and if found
  153.  * it does a root directory lookup for that file system and returns the
  154.  * result. THIS MAY BREAK ON FUTURE VERSIONS OF MINT; I don't recommend
  155.  * that you rely on internals of the file system routines!!!!!
  156.  */
  157.  
  158. #ifndef UNIDRV
  159. #define UNIDRV 'U'-'A'
  160. #endif
  161.  
  162. FILESYS *unifs;
  163.  
  164. long
  165. fake_root(drv, fc)
  166.     int drv;
  167.     fcookie *fc;
  168. {
  169.     fcookie dir;
  170.  
  171.     if (drv == fakedrv) {
  172.         unifs = fake_filesys.next;
  173.         while (unifs) {
  174.             if ( (*unifs->root)(UNIDRV, fc) == 0 ) {
  175.                 fc->fs = &fake_filesys;
  176.                 fc->dev = fakedrv;
  177.                 return 0;
  178.             }
  179.             unifs = unifs->next;
  180.         }
  181.         ALERT("Couldn't find file system for U:!");
  182.     }
  183.     fc->fs = 0;
  184.     return EDRIVE;
  185. }
  186.  
  187. /*
  188.  * all the other fake function drivers just call out to the unified
  189.  * file system to do their stuff
  190.  */
  191.  
  192. long
  193. fake_lookup(dir, name, fc)
  194.     fcookie *dir, *fc; char *name;
  195. {
  196.     if (!*name || (*name == '.' && (name[1] == 0 || name[1] == '.'))) {
  197.         *fc = *dir;
  198.         return 0;
  199.     }
  200.  
  201.     return (*unifs->lookup)(dir, name, fc);
  202. }
  203.  
  204. long
  205. fake_getxattr(fc, xattr)
  206.     fcookie *fc; XATTR *xattr;
  207. {
  208.     if (fc->index != 0L) {
  209.         ALERT("Bad getxattr call on fake file system");
  210.         return EFILNF;
  211.     }
  212.  
  213.     xattr->index = fc->index;
  214.     xattr->dev = fc->dev;
  215.     xattr->nlink = 1;
  216.     xattr->blksize = 1;
  217.     xattr->uid = xattr->gid = 0;
  218.     xattr->size = xattr->nblocks = 0;
  219.     xattr->mode = S_IFDIR | 0777;
  220.     xattr->attr = FA_DIR;
  221.     xattr->mtime = xattr->atime = xattr->ctime = 0;
  222.     xattr->mdate = xattr->adate = xattr->cdate = 0;
  223.     return 0;
  224. }
  225.  
  226. long
  227. fake_chattr(fc, attrib)
  228.     fcookie *fc; int attrib;
  229. {
  230.     return EACCDN;
  231. }
  232.  
  233. long
  234. fake_chown(fc, uid, gid)
  235.     fcookie *fc; int uid, gid;
  236. {
  237.     return EACCDN;
  238. }
  239.  
  240. long
  241. fake_chmode(fc, mode)
  242.     fcookie *fc;
  243.     unsigned mode;
  244. {
  245.     return EACCDN;
  246. }
  247.  
  248. long
  249. fake_rmdir(dir, name)
  250.     fcookie *dir;
  251.     char *name;
  252. {
  253.     return (*unifs->rmdir)(dir, name);
  254. }
  255.  
  256. long
  257. fake_remove(dir, name)
  258.     fcookie *dir;
  259.     char *name;
  260. {
  261.     return (*unifs->remove)(dir, name);
  262. }
  263.  
  264. long
  265. fake_getname(root, dir, name)
  266.     fcookie *root, *dir;
  267.     char *name;
  268. {
  269.     fcookie realroot;
  270.     fcookie realdir;
  271.  
  272.     (*unifs->root)(UNIDRV, &realroot);
  273.     realdir = *dir;
  274.     if (realdir.dev == fakedrv) {
  275.         realdir.dev = UNIDRV;
  276.         realdir.fs = unifs;
  277.     }
  278.  
  279.     return (*unifs->getname)(&realroot, &realdir, name);
  280. }
  281.  
  282. long
  283. fake_rename(olddir, oldname, newdir, newname)
  284.     fcookie *olddir, *newdir;
  285.     char *oldname, *newname;
  286. {
  287.     return (*unifs->rename)(olddir, oldname, newdir, newname);
  288. }
  289.  
  290. long
  291. fake_opendir(dirh, flags)
  292.     DIR *dirh; int flags;
  293. {
  294.     return (*unifs->opendir)(dirh, flags);
  295. }
  296.  
  297. long
  298. fake_readdir(dirh, nm, nmlen, fc)
  299.     DIR *dirh; char *nm; int nmlen; fcookie *fc;
  300. {
  301.     return (*unifs->readdir)(dirh, nm, nmlen, fc);
  302. }
  303.  
  304. long
  305. fake_rewinddir(dirh)
  306.     DIR *dirh;
  307. {
  308.     return (*unifs->rewinddir)(dirh);
  309. }
  310.  
  311. long
  312. fake_closedir(dirh)
  313.     DIR *dirh;
  314. {
  315.     return (*unifs->closedir)(dirh);
  316. }
  317.  
  318. long
  319. fake_pathconf(dir, which)
  320.     fcookie *dir; int which;
  321. {
  322.     return (*unifs->pathconf)(dir, which);
  323. }
  324.  
  325. long
  326. fake_dfree(dir, buf)
  327.     fcookie *dir; long *buf;
  328. {
  329.     return (*unifs->dfree)(dir, buf);
  330. }
  331.  
  332. DEVDRV *
  333. fake_getdev(fc, devsp)
  334.     fcookie *fc; long *devsp;
  335. {
  336.     return (*unifs->getdev)(fc, devsp);
  337. }
  338.  
  339. long
  340. fake_symlink(dir, name, to)
  341.     fcookie *dir; char *name, *to;
  342. {
  343.     return (*unifs->symlink)(dir, name, to);
  344. }
  345.  
  346. long
  347. fake_readlink(fc, buf, len)
  348.     fcookie *fc; char *buf; int len;
  349. {
  350.     return (*unifs->readlink)(fc, buf, len);
  351. }
  352.  
  353. long
  354. fake_dskchng(drv)
  355.     int drv;
  356. {
  357.     (void)GETBPB(drv);
  358.     return 0;
  359. }
  360.  
  361. /*
  362.  * and here are the fake drivers for the BIOS
  363.  */
  364.  
  365.  
  366. asm
  367. ("\
  368.     .globl    _newrwabs;     \
  369.     .globl    _newmediach;     \
  370.     .globl    _newgetbpb;     \
  371. _newgetbpb:            \
  372.     movew    sp@(4), d0;    \
  373.     cmpw    _fakedrv, d0;    \
  374.     beq    ret0;        \
  375.     movel    _oldgetbpb, a0;    \
  376.     jmp    a0@;        \
  377. ret0:                \
  378.     clrl    d0;        \
  379.     rts;            \
  380. _newmediach:            \
  381.     movew    sp@(4), d0;    \
  382.     cmpw    _fakedrv, d0;    \
  383.     beq    ret0;        \
  384.     movel    _oldmediach, a0; \
  385.     jmp    a0@;        \
  386. _newrwabs:            \
  387.     movew    sp@(0xe), d0;    \
  388.     cmpw    _fakedrv, d0;    \
  389.     beq    ret0;        \
  390.     movel    _oldrwabs, a0;    \
  391.     j